package com.boot.chap05;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.CompositeByteBuf;
import io.netty.buffer.Unpooled;

/**
 * @author renwq
 * @since 2021/9/19 21:30
 */
public class ByteBufExamples {

    private static final ByteBuf BYTE_BUF_FROM_SOMEWHERE = Unpooled.buffer(1024);

    public static void main(String[] args) {
        byteBufRelativeAccess();
    }

    // 顺序访问索引
    // nio flip()

    // 随机访问索引
    public static void byteBufRelativeAccess() {
        ByteBuf byteBuf = Unpooled.buffer(20);
        byteBuf.writeByte(4);
        byteBuf.writeByte(5);
        byteBuf.writeByte(2);
        for (int k=0; k<byteBuf.capacity(); k++) {
            byte b = byteBuf.getByte(k);
            System.out.printf("k: %s b: %s%n", k, (char)b);
        }
    }

    // 复合缓冲区
    public static void byteBufComposite() {
        CompositeByteBuf messageBuf = Unpooled.compositeBuffer();
        ByteBuf headerBuf = BYTE_BUF_FROM_SOMEWHERE; // can be backing or direct
        ByteBuf bodyBuf = BYTE_BUF_FROM_SOMEWHERE;   // can be backing or direct
        messageBuf.addComponents(headerBuf, bodyBuf);
        //...
        messageBuf.removeComponent(0); // remove the header
        for (ByteBuf buf : messageBuf) {
            System.out.println(buf.toString());
        }
    }

    // 直接缓冲区
    public static void directBuffer() {
        ByteBuf directBuf = BYTE_BUF_FROM_SOMEWHERE;
        if (!directBuf.hasArray()) { // 检查 ByteBuf 是否有一个 支撑数组, 如果不是 则这是一个 直接缓冲区
            int len = directBuf.readableBytes();
            byte[] arr = new byte[len];
            directBuf.getBytes(directBuf.readerIndex(), arr); // 将字节复制到 新数组
            handleArray(arr, 0, len);
        }
    }

    // 堆缓冲区
    public static void heapBuffer() {
        ByteBuf heapBuf = BYTE_BUF_FROM_SOMEWHERE;
        heapBuf.writeInt(4);
        heapBuf.writeInt(4);
        heapBuf.writeInt(4);
        if (heapBuf.hasArray()) { // 检查 ByteBuf 是否有一个 支撑数组
            byte[] arr = heapBuf.array(); // 获取该数据的引用
            int offset = heapBuf.arrayOffset() + heapBuf.readerIndex(); // 计算第一个字节的 偏移量
            int len = heapBuf.readableBytes(); // 获取可读字节数
            handleArray(arr, offset, len);
        }
    }

    private static void handleArray(byte[] array, int offset, int len) {
        System.out.printf("array.len: %s%noffset: %s%nlen: %s%n", array.length, offset, len);
    }
}
